package com.example.mq.mqserver.core;

import lombok.Data;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * 表示要传递的消息
 * Message 对象需要能够在网络上传输，并且可以写入文件中，因此需要实现序列化和反序列化。
 */
@Data
public class Message implements Serializable {
    // Message 的核心部分，包括基本属性和消息体
    private BasicProperties basicProperties = new BasicProperties();//基本属性
    private byte[] body;//消息体

    // 辅助属性，用于消息持久化时记录文件偏移量 [offsetBeg, offsetEnd)
    private transient long offsetBeg = 0;  // 消息开头在文件中的偏移量（字节）
    private transient long offsetEnd = 0;  // 消息结尾在文件中的偏移量（字节）

    // 用于标识消息在文件中是否有效（逻辑删除）
    // 0x1 表示有效，0x0 表示无效
    private byte isValid = 0x1;

    /**
     * 创建带有唯一 MessageId 的 Message 对象
     * 如果传入的 routingKey 与 basicProperties 中的 routingKey 冲突，以外部的为准
     */
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        // 生成唯一的 MessageId，以 M- 作为前缀
        message.setMessageId("M-" + UUID.randomUUID());
        message.setRoutingKey(routingKey);
        message.setBody(body);

        // offsetBeg, offsetEnd, isValid 在消息写入文件前设置
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }

    // 重写 toString 方法，便于调试和日志记录
    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}
